home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS02.ADF / Emacs / termio.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  8KB  |  298 lines

  1. /* termio.c, with improvements */
  2. /*
  3.  * The functions in this file negotiate with the operating system for
  4.  * characters, and write characters in a barely buffered fashion on the display.
  5.  * All operating systems.
  6.  */
  7. #include        <stdio.h>
  8. #include        "ed.h"
  9.  
  10. #if     AMIGA
  11. #define NEW 1006
  12. #define AMG_MAXBUF      1024
  13. static long terminal;
  14. static char     scrn_tmp[AMG_MAXBUF+1];
  15. static int      scrn_tmp_p = 0;
  16. #endif
  17.  
  18. #if     VMS
  19. #include        <stsdef.h>
  20. #include        <ssdef.h>
  21. #include        <descrip.h>
  22. #include        <iodef.h>
  23. #include        <ttdef.h>
  24.  
  25. #define NIBUF   128                     /* Input buffer size            */
  26. #define NOBUF   1024                    /* MM says bug buffers win!     */
  27. #define EFN     0                       /* Event flag                   */
  28.  
  29. char    obuf[NOBUF];                    /* Output buffer                */
  30. int     nobuf;                  /* # of bytes in above    */
  31. char    ibuf[NIBUF];                    /* Input buffer          */
  32. int     nibuf;                  /* # of bytes in above  */
  33. int     ibufi;                  /* Read index                   */
  34. int     oldmode[2];                     /* Old TTY mode bits            */
  35. int     newmode[2];                     /* New TTY mode bits            */
  36. short   iochan;                  /* TTY I/O channel             */
  37. #endif
  38.  
  39. #if     CPM
  40. #include        <bdos.h>
  41. #endif
  42.  
  43. #if     MSDOS
  44. #undef  LATTICE
  45. #include        <dos.h>
  46. #endif
  47.  
  48. #if RAINBOW
  49. #include "rainbow.h"
  50. #endif
  51.  
  52. #if V7
  53. #include        <sgtty.h>               /* for stty/gtty functions */
  54. struct  sgttyb  ostate;          /* saved tty state */
  55. struct  sgttyb  nstate;          /* values for editor mode */
  56. #endif
  57.  
  58. /*
  59.  * This function is called once to set up the terminal device streams.
  60.  * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns
  61.  * a channel to it and sets it raw. On CPM it is a no-op.
  62.  */
  63. ttopen()
  64. {
  65. #if     AMIGA
  66.         terminal = Open("RAW:1/1/639/199/MicroEmacs", NEW);
  67. #endif
  68. #if     VMS
  69.         struct  dsc$descriptor  idsc;
  70.         struct  dsc$descriptor  odsc;
  71.         char    oname[40];
  72.         int     iosb[2];
  73.         int     status;
  74.  
  75.         odsc.dsc$a_pointer = "SYS$INPUT";
  76.         odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  77.         odsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  78.         odsc.dsc$b_class        = DSC$K_CLASS_S;
  79.         idsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  80.         idsc.dsc$b_class        = DSC$K_CLASS_S;
  81.         do {
  82.                 idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  83.                 idsc.dsc$w_length  = odsc.dsc$w_length;
  84.                 odsc.dsc$a_pointer = &oname[0];
  85.                 odsc.dsc$w_length  = sizeof(oname);
  86.                 status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  87.                 if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  88.                         exit(status);
  89.                 if (oname[0] == 0x1B) {
  90.                         odsc.dsc$a_pointer += 4;
  91.                         odsc.dsc$w_length  -= 4;
  92.                 }
  93.         } while (status == SS$_NORMAL);
  94.         status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  95.         if (status != SS$_NORMAL)
  96.                 exit(status);
  97.         status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  98.                           oldmode, sizeof(oldmode), 0, 0, 0, 0);
  99.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  100.                 exit(status);
  101.         newmode[0] = oldmode[0];
  102.         newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
  103.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  104.                           newmode, sizeof(newmode), 0, 0, 0, 0);
  105.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  106.                 exit(status);
  107. #endif
  108. #if     CPM
  109. #endif
  110. #if     MSDOS
  111. #endif
  112. #if     V7
  113.         gtty(1, &ostate);                       /* save old state */
  114.         gtty(1, &nstate);                       /* get base of new state */
  115.         nstate.sg_flags |= RAW;
  116.         nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
  117.         stty(1, &nstate);                       /* set mode */
  118. #endif
  119. }
  120.  
  121. /*
  122.  * This function gets called just before we go back home to the command
  123.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  124.  * Another no-operation on CPM.
  125.  */
  126. ttclose()
  127. {
  128. #if     AMIGA
  129.         amg_flush();
  130.         Close(terminal);
  131. #endif
  132. #if     VMS
  133.         int     status;
  134.         int     iosb[1];
  135.  
  136.         ttflush();
  137.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  138.                  oldmode, sizeof(oldmode), 0, 0, 0, 0);
  139.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  140.                 exit(status);
  141.         status = SYS$DASSGN(iochan);
  142.         if (status != SS$_NORMAL)
  143.                 exit(status);
  144. #endif
  145. #if     CPM
  146. #endif
  147. #if     MSDOS
  148. #endif
  149. #if     V7
  150.         stty(1, &ostate);
  151. #endif
  152. }
  153.  
  154. /*
  155.  * Write a character to the display. On VMS, terminal output is buffered, and
  156.  * we just put the characters in the big array, after checking for overflow.
  157.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  158.  * MS-DOS (use the very very raw console output routine).
  159.  */
  160. ttputc(c)
  161. #if     AMIGA
  162.         char c;
  163. #endif
  164. {
  165. #if     AMIGA
  166.         scrn_tmp[scrn_tmp_p++] = c;
  167.         if(scrn_tmp_p>=AMG_MAXBUF)
  168.                 amg_flush();
  169. #endif
  170. #if     VMS
  171.         if (nobuf >= NOBUF)
  172.                 ttflush();
  173.         obuf[nobuf++] = c;
  174. #endif
  175.  
  176. #if     CPM
  177.         bios(BCONOUT, c, 0);
  178. #endif
  179.  
  180. #if     MSDOS & CWC86
  181.         dosb(CONDIO, c, 0);
  182. #endif
  183.  
  184. #if RAINBOW
  185.         Put_Char(c);                    /* fast video */
  186. #endif
  187.  
  188. #if     V7
  189.         fputc(c, stdout);
  190. #endif
  191. }
  192.  
  193. amg_flush()
  194. {
  195.         if(scrn_tmp_p)
  196.                 Write(terminal,scrn_tmp,scrn_tmp_p);
  197.         scrn_tmp_p = 0;
  198. }
  199.  
  200. /*
  201.  * Flush terminal buffer. Does real work where the terminal output is buffered
  202.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  203.  */
  204. ttflush()
  205. {
  206. #if     AMIGA
  207.         amg_flush();
  208. #endif
  209. #if     VMS
  210.         int     status;
  211.         int     iosb[2];
  212.  
  213.         status = SS$_NORMAL;
  214.         if (nobuf != 0) {
  215.                 status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  216.                          iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  217.                 if (status == SS$_NORMAL)
  218.                         status = iosb[0] & 0xFFFF;
  219.                 nobuf = 0;
  220.         }
  221.         return (status);
  222. #endif
  223. #if     CPM
  224. #endif
  225. #if     MSDOS
  226. #endif
  227. #if     V7
  228.         fflush(stdout);
  229. #endif
  230. }
  231.  
  232. /*
  233.  * Read a character from the terminal, performing no editing and doing no echo
  234.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  235.  * simple on CPM, because the system can do exactly what you want.
  236.  */
  237. ttgetc()
  238. {
  239. #if     AMIGA
  240.         char ch;
  241.         amg_flush();
  242.         Read(terminal, &ch, 1);
  243.         return (int) ch;
  244. #endif
  245. #if     VMS
  246.         int     status;
  247.         int     iosb[2];
  248.         int     term[2];
  249.  
  250.         while (ibufi >= nibuf) {
  251.                 ibufi = 0;
  252.                 term[0] = 0;
  253.                 term[1] = 0;
  254.                 status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  255.                          iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  256.                 if (status != SS$_NORMAL)
  257.                         exit(status);
  258.                 status = iosb[0] & 0xFFFF;
  259.                 if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  260.                         exit(status);
  261.                 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  262.                 if (nibuf == 0) {
  263.                         status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  264.                                  iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  265.                         if (status != SS$_NORMAL
  266.                         || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  267.                                 exit(status);
  268.                         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  269.                 }
  270.         }
  271.         return (ibuf[ibufi++] & 0xFF);    /* Allow multinational  */
  272. #endif
  273.  
  274. #if     CPM
  275.         return (biosb(BCONIN, 0, 0));
  276. #endif
  277.  
  278. #if RAINBOW
  279.         int Ch;
  280.  
  281.         while ((Ch = Read_Keyboard()) < 0);
  282.  
  283.         if ((Ch & Function_Key) == 0)
  284.                 if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
  285.                         Ch &= 0xFF;
  286.  
  287.         return Ch;
  288. #endif
  289.  
  290. #if     MSDOS & MWC86
  291.         return (dosb(CONRAW, 0, 0));
  292. #endif
  293.  
  294. #if     V7
  295.         return(fgetc(stdin));
  296. #endif
  297. }
  298.